/**
* @describe 社交游戏socket类
* @author 游金宇(KM)
* @date 2024-09-12 11:41:27
*/


import { BattleInitialData, JoinBattleResponse, Player as BasePlayer, SocialGameClientOption, Event as SGCEvent, WatchBroadcastMessage, BattleInitialDataSchema, PlayerSchema, WatchBroadcastMessageSchema, ClientOption, RoomEvent, Room, RoomSchema, SeatSwapApplySchema, RoomKickSchema, IMMessageSchema, IMMessage, BattleCountdownStartSchema } from 'sgc'
import { DescMessage, Message, toJson } from "@bufbuild/protobuf";
import { error, Game, game, log } from 'cc';

import { Event, Route } from '../../../pb-generate/server/[项目名]/[分支名]/v1/router_pb';

import { cat, Manager, WrapperSocialGameClient } from '@shimotsuki/core';
import { ReflectMessage } from '@bufbuild/protobuf/reflect';

import { FinishedMiniSchema, GameBoutStartSchema, GameStartSchema, SelectLeadBroadcastSchema, ShowCardBroadcastSchema, SyncResponseSchema } from '../../../pb-generate/server/[项目名]/[分支名]/v1/msg_pb';

import { ReportGameStateRequest_GameSettlePayloadSchema, ReportGameStateRequestSchema } from '../../../pb-generate/server/[项目名]/[分支名]/v1/report_battle_pb';

import { DEBUG, WECHAT } from 'cc/env';

/**基础事件 */
export type BsseSocketEvent = keyof typeof SGCEvent;

/**业务事件 */
export type BusinessSocketEvent = keyof typeof Event;

/**异步路由 */
export type ASYNCSocketRoute = keyof typeof Route;

/**路由 */
export type SocketRoute = keyof typeof Route;

export type SocketEvent = BusinessSocketEvent | BsseSocketEvent | ASYNCSocketRoute | RoomEvent

// 事件响应类型
type EventResponsePair<T extends SocketEvent> = { event: T, responseType: DescMessage, cb?: (data: Message) => void };


declare module '@shimotsuki/core' {
    interface Manager {
        game_ws: RouteRequestWrapper
    }
}

/**路由Request封装 */
class RouteRequestWrapper extends WrapperSocialGameClient {
    /**日志黑名单 */
    // override logBlackList: SocketEvent[] = ['WatchBroadcast']

}


/**战局事件对 */
export const BattleEventResponsePairs: EventResponsePair<BsseSocketEvent>[] = [
    // 战局初始化- 广播，协议名称：BattleInitialize，返回参数：EmptyResponse
    { event: 'BattleInitialize', responseType: BattleInitialDataSchema },

    // 玩家状态变更推送- 广播，协议名称：PlayerStatusChanged，返回参数：EmptyResponse
    { event: 'PlayerStatusChanged', responseType: PlayerSchema },

    // 观战 - 广播，协议名称：WatchBroadcast，返回参数：WatchBroadcastMessage
    { event: 'WatchBroadcast', responseType: WatchBroadcastMessageSchema },

]

/**游戏事件对 */
export const GameEventResponsePairs: EventResponsePair<BusinessSocketEvent | ASYNCSocketRoute>[] = [
    // 游戏开始-广播
    { event: 'EVENT_GAME_START', responseType: GameStartSchema },

    // 状态广播-广播
    { event: 'EVENT_STATE_BROADCAST', responseType: SyncResponseSchema },

    // 游戏回合开始-广播
    { event: 'EVENT_GAME_BOUT_START', responseType: GameBoutStartSchema },

    //出牌-广播
    { event: 'EVENT_SHOW_CARD', responseType: ShowCardBroadcastSchema },

    // 选择引线-广播
    { event: 'EVENT_SELECT_LEAD', responseType: SelectLeadBroadcastSchema },

    // 小结算-广播
    { event: 'EVENT_FINISHED_MINI', responseType: FinishedMiniSchema },

    // 结算广播第一次-广播
    { event: 'EVENT_FINISHED_ONE', responseType: ReportGameStateRequest_GameSettlePayloadSchema },

    // 结算广播第二次-广播
    { event: 'EVENT_FINISHED_TWO', responseType: ReportGameStateRequestSchema },

    // //AI修改
    // { event: 'EVENT_AI_DATA', responseType: AIData },
    // 扩展添加其他路由和响应类型TODO
]

export const CreateGameWebSocket = ({
    battle_id = '',
    serverId = '',
    token = ''
}: Partial<SocialGameClientOption> = {}) => {
    log('创建game ws', battle_id, serverId, token)
    return cat.game_ws = cat.socialGameClient.createWebSocket(
        'game',
        {
            url: cat.env.player_ws_url,
            debug: DEBUG,
            isArrayBuffer: WECHAT
        },
        {
            battle_id,
            serverId,
            token: token ?? cat.store.game.game_token
        },
        {
            dynamicEvents: new Map([...BattleEventResponsePairs, ...GameEventResponsePairs].map(({ event, responseType, cb }) => [event, { event, responseType, cb }]))
        }
    )
}
